from langchain.tools import tool
import yt_dlp
from pathlib import Path
from datetime import datetime
from dotenv import load_dotenv
import boto3
import os
from typing import Dict, Any, Optional, List
from bilibili_api.user import User, VideoOrder
from app.core.config import POSTER_INFO
from langchain_tavily import TavilySearch
import warnings
from datetime import datetime

load_dotenv()


@tool
def download_bibili_audio(url: str) -> dict:
    """
    下载B站视频的音频，固定为m4a格式
    
    Args:
        url: B站视频URL
        
    Returns:
        下载结果字典，含文件路径
    """
    output_dir = "downloads"
    timestamp = datetime.now().strftime("%Y%m%d%H%M")

    # 创建输出目录
    Path(output_dir).mkdir(exist_ok=True)
    
    ydl_opts = {
        'outtmpl': f'{output_dir}/{timestamp}.%(ext)s',
        'format': 'bestaudio/best',  # 下载最佳音频质量，保持原格式
    }
    
    try:
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            info = ydl.extract_info(url, download=True)
            # 获取实际的文件扩展名
            ext = info.get('ext', 'm4a')
            actual_file_path = f'{output_dir}/{timestamp}.{ext}'
            
        return {
            'success': True,
            'file_path': actual_file_path
        }
    except Exception as e:
        return {
            'success': False,
            'error': str(e)
        }

# print(download_bibili_audio("https://www.bilibili.com/video/BV1i9snzPEDq"))
@tool
def upload_to_oss(file_path: str) -> dict:
    """
    上传文件到OSS，上传成功后删除本地文件
    
    Args:
        file_path: 本地文件路径
        
    Returns:
        上传结果字典
    """
    try:
        file_name = file_path.split("/")[-1]
        client = boto3.client(
                's3',
                aws_access_key_id=os.getenv("S3_ACCESS_KEY"),
                aws_secret_access_key=os.getenv("S3_SECRET_KEY"),
                endpoint_url=os.getenv("S3_ENDPOINT"),
                region_name=os.getenv("S3_REGION"),
            )

        # 上传文件到OSS
        client.upload_file(
            Filename=file_path,
            Bucket=os.getenv("S3_BUCKET_NAME"),
            Key=f"audio/{file_name}",
        )

        # 上传成功后删除本地文件
        if os.path.exists(file_path):
            os.remove(file_path)
        
        return {
            'success': True,
            'file_url': f"{os.getenv('S3_ENDPOINT')}/{os.getenv('S3_BUCKET_NAME')}/audio/{file_name}",
            'message': '文件上传成功'
        }
    except Exception as e:
        return {
            'success': False,
            'error': str(e),
            'message': '文件上传失败'
        }

# print(upload_to_oss("downloads/tmp_audio.m4a"))

def get_poster_info() -> dict:
    """
    直接调用，获取全部相关b站博主信息
    
    Args:
        poster_name: 发布者名称
        
    Returns:
        发布者信息字典, 包含uid, username, keyword, homepage    
    """
    return POSTER_INFO

@tool
async def get_poster_latest_video(uid: int, keyword: str) -> Optional[Dict[str, Any]]:
    """
    获取相关b站博主最新与AI新闻相关视频信息
    
    Args:
        uid: 发布者UID
        keyword: 搜索关键词
        
    Returns:
        此博主最新与AI新闻相关视频信息字典, 包含title, bvid, url, description, length, created
        其中description包含视频描述，可能包含相关内容的链接，是重要信息
    """
    user = User(uid=uid)
    resp = await user.get_videos(ps=50, pn=1, order=VideoOrder.PUBDATE, keyword=keyword)
    try:
        vlist: List[Dict[str, Any]] = resp["list"]["vlist"]
    except Exception:
        return None
    if not vlist:
        return None
    v = vlist[0]
    
    url = f"https://www.bilibili.com/video/{v.get('bvid', '')}"

    return {
        "title": v.get("title", ""),
        "bvid": v.get("bvid", ""),
        "url": url,
        "description": v.get("description", ""),
        "length": v.get("length", ""),
        "created": datetime.fromtimestamp(int(v.get("created", 0))).strftime("%Y-%m-%d"),
    }


warnings.filterwarnings("ignore", category=UserWarning, module="wikipedia")
@tool
async def search_web(query: str, max_results: int = 2):
    """ 网络搜索，返回内容列表
    """
    try:
        # 使用TavilySearch工具
        search_web_tool = TavilySearch(
            max_results=max_results,
            topic="news",
            include_answer="advanced",
            include_raw_content=False,
            search_depth="advanced",
            tavily_api_key=os.getenv("TAVILY_API_KEY"),
        )
        
        search_docs = await search_web_tool.ainvoke(query)
        
        
        

        
        return search_docs
        
    except Exception as e:
        print(f"搜索过程中出错: {e}")
        return [f"搜索失败: {str(e)}"]

async def quick_read_video(bvid: str) -> Optional[Dict[str, Any]]:
    """
    快速读取视频音频内容
    
    Args:
        bvid: 视频bvid  get_ai_conclusion()
        
    Returns:
        视频音频内容字典, 包含success, file_path, file_url, message
    """